﻿// HSS.ServiceModel.Internal.VirtualServiceHelper.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       VirtualServiceHelper.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/04/2010
// ----------------------------------------------------------------------------
namespace HSS.ServiceModel.Internal
{
	#region Using Directives
	using System;
	using System.ServiceModel;
	using System.ServiceModel.Channels;
	#endregion

	#region VirtualServiceHelper
	/// <summary>
	/// VirtualServiceHelper
	/// </summary>
#if !DEBUG
	[System.Diagnostics.DebuggerStepThroughAttribute()]
#endif
	internal static class VirtualServiceHelper
	{
#if SILVERLIGHT

		/// <summary>
		/// Gets a CustomBinding (BinaryBinding) for the specified EndpointAddress with the proper BasicHttpSecurityMode based on the Endpoint UriScheme.
		/// </summary>
		/// <param name="ep">The EndpointAddress to get the binding for</param>
		/// <param name="serviceToken">The token used to confirm the caller of this service is legitimate.</param>
		/// <returns>A CustomBinding for the requested Endpoint</returns>
		public static CustomBinding GetBinding(EndpointAddress ep, string serviceToken)
		{
			return GetBinding(ep.Uri.Scheme, new VirtualServiceInspector(serviceToken));
		}
		/// <summary>
		/// Based on the Type Name of a Service, gets an Endpoint Address for that current service.
		/// </summary>
		/// <param name="servicePath">The virtual path that is providing accecss to VirtualServices.</param>
		/// <param name="serviceName">The Type Name for the Service (the FullName of the server side Type including it's Namespace)</param>
		/// <returns>An EndpointAddress to the requested Service</returns>
		public static EndpointAddress GetEndpoint(string servicePath, string serviceName)
		{
			if (!servicePath.StartsWith("/", StringComparison.OrdinalIgnoreCase))
				servicePath = "/" + servicePath;
			if (!servicePath.EndsWith("/", StringComparison.OrdinalIgnoreCase))
				servicePath = servicePath + "/";
			return new EndpointAddress(GetRelativeUrlString(servicePath + serviceName + ".svc"));
		}

		private static string GetRelativeUrlString(string resourceRelativeUri)
		{
			return GetRelativeUrl(resourceRelativeUri).ToString();
		}
		private static Uri GetRelativeUrl(string resourceRelativeUri)
		{
			var source = System.Windows.Application.Current.Host.Source;
			var baseUri = source.ToString().Replace(source.LocalPath, string.Empty);
			var uriBase = new Uri(baseUri);
			return new Uri(uriBase, resourceRelativeUri);
		}
		private static BinaryMessageEncodingBindingElement GetEncoding()
		{
			BinaryMessageEncodingBindingElement encoding = new BinaryMessageEncodingBindingElement();
			return encoding;
		}
		private static TransportBindingElement GetTransport(BasicHttpSecurityMode mode)
		{
			TransportBindingElement transport;
			if (mode != BasicHttpSecurityMode.Transport)
				transport = new HttpTransportBindingElement();
			else
				transport = new HttpsTransportBindingElement();
			transport.MaxReceivedMessageSize = 0x7fffffffL;
			return transport;
		}
		private static CustomBinding GetBinding(string scheme, IMessageInspector messageInspector)
		{
			BasicHttpSecurityMode mode;
			if (scheme == Uri.UriSchemeHttp)
				mode = BasicHttpSecurityMode.None;
			else
				mode = BasicHttpSecurityMode.Transport;

			var elements = new BindingElementCollection();
			if (null != messageInspector)
				elements.Add(new MessageInspectorBindingElement() { MessageInspector = messageInspector });
			elements.Add(GetEncoding());
			elements.Add(GetTransport(mode));

			var b = new CustomBinding(elements.Clone()) { Name = "binaryHttpBinding" };

			return b;
		}

#else

		/// <summary>
		/// Gets a CustomBinding (BinaryBinding) for the specified EndpointAddress with the proper BasicHttpSecurityMode based on the Endpoint UriScheme.
		/// </summary>
		/// <param name="ep">The EndpointAddress to get the binding for</param>
		/// <param name="serviceToken">The token used to confirm the caller of this service is legitimate.</param>
		/// <param name="userName">The users UserName.</param>
		/// <param name="password">The users Password.</param>
		/// <returns>A CustomBinding for the requested Endpoint</returns>
		public static CustomBinding GetBinding(EndpointAddress ep, string serviceToken, string userName, string password)
		{
			BasicHttpSecurityMode mode;
			if (ep.Uri.Scheme == Uri.UriSchemeHttp)
				mode = BasicHttpSecurityMode.None;
			else
				mode = BasicHttpSecurityMode.Transport;

			var elements = new BindingElementCollection();
			elements.Add(new MessageInspectorBindingElement() { MessageInspector = new VirtualServiceInspector(serviceToken) });
			elements.Add(new MessageInspectorBindingElement() { MessageInspector = new VirtualServiceCredentials(userName, password) });
			elements.Add(GetEncoding());
			elements.Add(GetTransport(mode));

			var b = new CustomBinding(elements.Clone()) { Name = "binaryHttpBinding" };

			return b;
		}

		private static BinaryMessageEncodingBindingElement GetEncoding()
		{
			BinaryMessageEncodingBindingElement encoding = new BinaryMessageEncodingBindingElement();
			return encoding;
		}
		private static TransportBindingElement GetTransport(BasicHttpSecurityMode mode)
		{
			TransportBindingElement transport;
			if (mode != BasicHttpSecurityMode.Transport)
				transport = new HttpTransportBindingElement();
			else
				transport = new HttpsTransportBindingElement();
			transport.MaxReceivedMessageSize = 0x7fffffffL;
			return transport;
		}

#endif
	}
	#endregion
}